﻿using System;
using System.Data.SQLite;
using System.Linq;
using CompactMapper.Orm.UnitOfWork;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace CompactMapper.Orm.Tests
{
    /// <summary>
    /// Summary description for UnitTest1
    /// </summary>
    [TestClass]
    public class MusicDatabaseTests : MusicDatabaseTestsBase
    {

        [TestMethod]
        public void OrmBasicTests_OneToManyRelationships()
        {
            using (var unitOfWork = GetKeyedUnitOfWork<Artist>())
            {
                var theArtist = unitOfWork.GetAll().Single();
                Assert.AreEqual(MusicDatabasePopulation.ArtistName, theArtist.ArtistName);
                Assert.AreEqual(1, theArtist.Tracks.Count());
                Assert.AreEqual(2, theArtist.Records.Count());
                Assert.IsTrue(theArtist.Tracks.Single().TrackName.Equals(MusicDatabasePopulation.SongName));
                Assert.AreEqual(MusicDatabasePopulation.Publisher, theArtist.Tracks.Single().Publisher.Name);
                Assert.IsTrue(theArtist.Records.Any(aRecord => aRecord.RecordName.Equals(MusicDatabasePopulation.RecordName2)));
                Assert.IsTrue(theArtist.Records.Any(aRecord => aRecord.RecordName.Equals(MusicDatabasePopulation.RecordName1)));
                Assert.IsTrue(theArtist.Records.All(aRecord => aRecord.Publisher.Name.Equals(MusicDatabasePopulation.Publisher)));
                Assert.AreEqual(MusicDatabasePopulation.SongName, theArtist.Records.First().Tracks.Single().TrackName);
                Assert.AreEqual(MusicDatabasePopulation.SongName, theArtist.Records.Last().Tracks.Single().TrackName);
            }
        }

        [TestMethod]
        public void OrmBasicTests_MultiInsertions()
        {
            using (var unitOfWork = GetKeyedUnitOfWork<Label>())
            {
                Assert.AreEqual(MusicDatabasePopulation.Label1, unitOfWork.GetAll().First().Name);
                Assert.AreEqual(MusicDatabasePopulation.Label2, unitOfWork.GetAll().Last().Name);
            }
        }

        [TestMethod]
        public void OrmBasicTests_DeleteCascade()
        {
            try
            {

                using (var unitOfWork = GetKeyedUnitOfWork<Artist>())
                {
                    Assert.IsTrue(unitOfWork.GetAll().Single().Tracks.Any());
                }

                //Delete
                using (var unitOfWork = GetKeyedUnitOfWork<Artist>())
                {
                    unitOfWork.Delete(MusicDatabasePopulation.Artist.Key);
                }
                using (var unitOfWork = GetKeyedUnitOfWork<Artist>())
                {
                    Assert.IsFalse(unitOfWork.GetAll().Any());
                }
                //Cascades
                using (var unitOfWork = (SqLiteKeyedUnitOfWork<Track>)GetKeyedUnitOfWork<Track>())
                {
                    var command = new SQLiteCommand(String.Format("SELECT * FROM {0}", typeof(Track).Name));
                    using (var reader = unitOfWork.GetReader(command))
                        Assert.IsFalse(reader.HasRows);
                }
            }
            finally
            {
                MusicDatabasePopulation.Populate(GetKeyedUnitOfWork<Artist>());
            }
        }


        [TestMethod]
        public void OrmBasicTests_DeleteAll()
        {
            try
            {
                using (var unitOfWork = GetKeyedUnitOfWork<Label>())
                {
                    Assert.AreEqual(2, unitOfWork.GetAll().Count());
                    unitOfWork.DeleteAll();
                    Assert.AreEqual(0, unitOfWork.GetAll().Count());
                }
            }
            finally
            {
                MusicDatabasePopulation.Populate(GetKeyedUnitOfWork<Label>());
            }
        }
    }
}
